﻿// This File is part of Innovation Foundry's "QualityHelper Project"
//
// Copyright  2009 Innovation Foundry Pty Ltd
// All rights reserved
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the
// Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA  02110-1301 USA
// or alternatively it may be downloaded from <http://www.gnu.org/licenses/>.

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.Collections.Generic;
using System.Windows.Browser;

namespace InnovationFoundry.QualityHelper.Utilities
{
    public class CloneHelper
    {
        public static T Clone<T>(T source)
        {
            T cloned = (T)Activator.CreateInstance(source.GetType());
            foreach (PropertyInfo curPropInfo in source.GetType().GetProperties())
            {

                if (curPropInfo.GetGetMethod() != null

                    && (curPropInfo.GetSetMethod() != null))
                {

                    // Handle Non-indexer properties

                    if (curPropInfo.Name != "Item")
                    {

                        // get property from source

                        object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] { });



                        // clone if needed

                        if (getValue != null && getValue is DependencyObject)

                            getValue = Clone((DependencyObject)getValue);



                        // set property on cloned

                        curPropInfo.GetSetMethod().Invoke(cloned, new object[] { getValue });

                    }

                        // handle indexer

                    else
                    {

                        // get count for indexer

                        int numberofItemInColleciton =

                            (int)

                            curPropInfo.ReflectedType.GetProperty("Count").GetGetMethod().Invoke(source, new object[] { });



                        // run on indexer

                        for (int i = 0; i < numberofItemInColleciton; i++)
                        {

                            // get item through Indexer

                            object getValue = curPropInfo.GetGetMethod().Invoke(source, new object[] { i });



                            // clone if needed

                            if (getValue != null && getValue is DependencyObject)

                                getValue = Clone((DependencyObject)getValue);

                            // add item to collection

                            curPropInfo.ReflectedType.GetMethod("Add").Invoke(cloned, new object[] { getValue });

                        }

                    }

                }

            }



            return cloned;

        }
        
    }


}
